# coding:utf-8

import os
import yaml
import requests
import re
import base64
import traceback
from configparser import ConfigParser

"""
觅思文档导出的文集导入觅思文档
"""


# 导入文集
class Joplin2Mrdoc():
    def __init__(self):
        self.mrdoc_url = MRDOC_URL
        self.mrdoc_token = MRDOC_TOKEN
        self.base_path = BASE_PATH
        self.toc_item_list = []
        self.toc_id_map = {}
        self.total_doc = 0
        self.total_img = 0

    # 树转列表
    def tree2list(self, item, parent=0):
        i = {
            'id': item['id'],
            'name': item['name'],
            'file': item['file'],
            'editor_mode': item['editor_mode'] if 'editor_mode' in item.keys() else 1,
            'parent': parent,
        }
        if i not in self.toc_item_list and i['id'] != i['parent']:
            # print(1, i)
            self.toc_item_list.append(i)
        if 'children' in item.keys() and len(item['children']) > 0:
            for i in item['children']:
                ci = {
                    'id': i['id'],
                    'name': i['name'],
                    'file': i['file'],
                    'editor_mode': i['editor_mode'] if 'editor_mode' in i.keys() else 1,
                    'parent': item['id']
                }
                if ci not in self.toc_item_list:
                    # print(0,item)
                    self.toc_item_list.append(ci)
                self.tree2list(i, parent=item['id'])

    # 工作方法
    def work(self):
        for dir in os.listdir(self.base_path):
            if dir == '_resources':
                continue
            print(">>>发现笔记本：",dir)
            try:
                # 新建文集
                project_info = {
                    'name': dir,
                }
                project_created = self.create_project(info=project_info)
                # print(project_created)
                if project_created['status']:
                    print("+已新建文集：", dir)
                    project_id = project_created['data']
                else:
                    print("[x]新建文集出错，导入终止！")
                    raise Exception

                # 遍历临时文件夹中的所有文件和文件夹
                project_path = os.path.join(self.base_path,dir)
                for f in os.listdir(project_path):
                    # 获取 .md 文件
                    if f.endswith('.md'):
                        print(">处理本地文档：", f)
                        # 读取 .md 文件文本内容
                        with open(os.path.join(project_path, f), 'r', encoding='utf-8') as md_file:
                            doc_content = md_file.read()
                            doc_content = self.convert_doc_img(doc_content)
                            # 新建文档
                            doc_info = {
                                'pid': project_id,
                                'title': f[:-3],
                                'doc': doc_content,
                                'editor_mode': 1,
                            }
                            doc_created = self.create_doc(info=doc_info)
                            if doc_created['status']:
                                self.total_doc += 1
                                print("+已导入文档：", f[:-3])

                print(">>>导入完成！")
                print("导入文档数：", self.total_doc)
                print("转存图片数：", self.total_img)
            except Exception as e:
                print("[x]解析导入文件异常：", repr(e))
                print(traceback.print_exc())

    def convert_doc_img(self, doc):
        # 查找MD语法的静态文件
        pattern = r"\!\[.*?\]\(.*?\)"
        media_list = re.findall(pattern, doc)
        if len(media_list) > 0:
            for media in media_list:
                media_filename = media.split("(")[-1].split(")")[0]  # 媒体文件的文件名
                # 存在本地图片路径
                if media_filename.startswith("../_resources"):
                    # 判断本地图片路径是否存在
                    temp_media_file_path = os.path.join(self.base_path, media_filename[3:])
                    if os.path.exists(temp_media_file_path):
                        print(">发现本地图片：", media_filename)
                        # 如果存在，上传本地图片
                        is_upload_img = self.upload_img(path=temp_media_file_path)
                        if 'success' in is_upload_img.keys() and is_upload_img['success'] == 1:
                            print("+转存图片成功：", media_filename)
                            self.total_img += 1
                            doc = doc.replace(media_filename, is_upload_img['url'])

        # 查找<img>标签形式的静态图片
        img_pattern = r'<img[^>]*/>'
        img_list = re.findall(img_pattern, doc)
        if len(img_list) > 0:
            for img in img_list:
                media_src = re.findall('src="([^"]+)"', img)
                if len(media_src) > 0:
                    media_filename = media_src[0]
                else:
                    break

                # 存在本地图片路径
                if media_filename.startswith("../_resources"):
                    # 判断本地图片路径是否存在
                    temp_media_file_path = os.path.join(self.base_path, media_filename[3:])
                    if os.path.exists(temp_media_file_path):
                        print(">发现本地图片：", media_filename)
                        # 如果存在，上传本地图片
                        is_upload_img = self.upload_img(path=temp_media_file_path)
                        if 'success' in is_upload_img.keys() and is_upload_img['success'] == 1:
                            print("+转存图片成功：", media_filename)
                            self.total_img += 1
                            doc = doc.replace(media_filename, is_upload_img['url'])

        return doc

    # 新建文集
    def create_project(self, info):
        resp = requests.post(self.mrdoc_url + "/api/create_project/?token=" + self.mrdoc_token, data=info)
        return resp.json()

    # 新建文档
    def create_doc(self, info):
        resp = requests.post(self.mrdoc_url + "/api/create_doc/?token=" + self.mrdoc_token, data=info)
        return resp.json()

    # 上传图片
    def upload_img(self, path):
        with open(path, 'rb') as img:
            img_base = base64.b64encode(img.read())
            resp = requests.post(self.mrdoc_url + "/api/upload_img/?token=" + self.mrdoc_token, data={"data": img_base})
            # print(resp.json())
            return resp.json()


if __name__ == '__main__':
    print("""
       _             _ _         ___    __  __      _____             
      | |           | (_)       |__ \  |  \/  |    |  __ \            
      | | ___  _ __ | |_ _ __      ) | | \  / |_ __| |  | | ___   ___ 
  _   | |/ _ \| '_ \| | | '_ \    / /  | |\/| | '__| |  | |/ _ \ / __|
 | |__| | (_) | |_) | | | | | |  / /_  | |  | | |  | |__| | (_) | (__ 
  \____/ \___/| .__/|_|_|_| |_| |____| |_|  |_|_|  |_____/ \___/ \___|
              | |                                                     
              |_|                                                     

【Joplin笔记本 Markdown 文档导入到觅思文档】 v20240429
    """)
    CONFIG = ConfigParser()
    CONFIG.read(os.path.join('./config.ini'), encoding='utf-8')

    MRDOC_URL = CONFIG.get("mrdoc", "url", fallback="")
    if MRDOC_URL == "":
        MRDOC_URL = input("1)请输入你的觅思文档地址:")
    else:
        print("1)你配置的觅思文档地址为：", MRDOC_URL)
    if MRDOC_URL.endswith("/"):
        MRDOC_URL = MRDOC_URL[:-1]

    MRDOC_TOKEN = CONFIG.get("mrdoc", "token", fallback="")
    if MRDOC_TOKEN == "":
        MRDOC_TOKEN = input("2)请输入你的觅思文档用户 Token:")
    else:
        print("2)你配置的觅思文档用户Token为:", MRDOC_TOKEN)

    BASE_PATH = CONFIG.get("mrdoc", "dir", fallback="")
    if BASE_PATH == "":
        BASE_PATH = input("3)请输入待导入文件夹路径:")
    else:
        print("3)你配置的待导入文件夹路径为:", BASE_PATH)

    if os.path.exists(BASE_PATH):
        op = Joplin2Mrdoc()
        op.work()
    else:
        print("[x]错误：目标文件夹不存在！")
    os.system('pause')

